﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;

namespace Coslen.Framework.Helpers
{
    /// <summary>
    /// Original Source: https://github.com/tapmantwo/MvcExtensions/blob/master/MvcExtensions/CheckboxList.cs
    /// </summary>
    public static class CheckBoxListHelpers
    {
        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression,
            MultiSelectList selectList,
            int numberOfColumns)
        {
            return CheckBoxListFor<TModel, TProperty>(
                htmlHelper,
                expression,
                selectList,
                null,
                numberOfColumns);
        }

        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression,
            MultiSelectList selectList,
            IDictionary<string, object> htmlAttributes,
            int numberOfColumns)
        {
            string name = ExpressionHelper.GetExpressionText(expression);
            name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

            // Get the property (and assume IEnumerable)
            IEnumerable currentValues = htmlHelper.ViewData.Model != null
                                            ? (IEnumerable)expression.Compile().Invoke(htmlHelper.ViewData.Model)
                                            : null;

            int columnCount = 0;
            var sb = new StringBuilder();
            foreach (var option in selectList)
            {
                if (columnCount % numberOfColumns == 0)
                {
                    // add wrapper
                    sb.AppendFormat("<div class=\"checkBoxListRow\">");
                }

                
                sb.AppendFormat("<div class=\"checkBoxListItem\">");

                sb.AppendFormat("   <div class=\"checkBoxListItemInput\">");

                var builder = new TagBuilder("input");
                if (ShouldItemBeSelected(option, currentValues))
                {
                    builder.MergeAttribute("checked", "checked");
                }

                builder.MergeAttributes<string, object>(htmlAttributes);
                builder.MergeAttribute("type", "checkbox");
                builder.MergeAttribute("value", option.Value);
                builder.MergeAttribute("name", name);
                sb.Append(builder.ToString(TagRenderMode.Normal));

                sb.AppendFormat("   </div>");

                sb.AppendFormat("   <div class=\"checkBoxListItemText\">" + option.Text + "</div>");

                sb.AppendFormat("</div>");

                if (columnCount % numberOfColumns == numberOfColumns - 1)
                {
                    // close wrapper
                    sb.AppendFormat("</div>");
                }

                columnCount++;


            }
            return MvcHtmlString.Create(sb.ToString());
        }

        private static bool ShouldItemBeSelected(SelectListItem item, IEnumerable selectedValues)
        {
            bool selected = false;
            if (null != selectedValues)
            {
                var enumerator = selectedValues.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    var currentValueAsString = (string)Convert.ChangeType(enumerator.Current, typeof(string));
                    selected = string.Equals(currentValueAsString, item.Value);
                    if (selected)
                        break;
                }
            }
            return selected;
        }
    }
}
